package com.lc.midi.script;


import com.lc.midi.keyEvent.KeyEvent;
import com.lc.midi.keyEvent.KeyEvents;
import com.lc.midi.keyEvent.MidiKey;

public class JsScript implements IScript {
	
	static final String IMEI_STRING = 
			"var imei = device.getIMEI();\n" +
			"if (imei == null || imei == \"\")" +
			"	imei = device.getMacAddress();\n" +
			"var im = 0;\n" +
			"for (i = 0; i < imei.length; i++)" +
			"    im += imei.charCodeAt(i);\n";
	
	static final String HEAD = 
			"var S = 1;"+"\n"+
			"//S为脚本播放的倍速，越大越快"+"\n"+
			"var w = Math.min(device.width,device.height);var h=Math.max(device.width,device.height);" +
			"var Y = w;"+"\n"+
			"var X = h/%d.0;"+"\n"+
			"var Y1=Y/16;"+"\n"+
			"var Y2=Y1*3;"+"\n"+
			"Y1=Y-Y1;"+"\n"+
			"Y2=Y-Y2;"+"\n"+
			"//toast(\"%d秒后开始演奏\");"+"\n"+
			"sleep(%d);"+"\n";
	static final String HEAD_PERFACT = HEAD.replace("Y2=Y1*3", "Y2=Y1*8");
	
//	private String enctypt0x(String data, boolean ts) throws Exception{
//		String baseEn = "var _0x24d6 = ['RU5E', 'c2VyaWFs', 'dW5rbm93bg==', 'M+enkuWQjuW8gOWni+W8ueWljw==', '5L2c6ICF77ya5Y+y6I6x5YWL5Li2UVE7MTAwMzgxNDEwNA==', 'd2lkdGg=', 'aGVpZ2h0'];\r\n" +
//				"(function(_0x1007cb, _0xce2c82) {var _0x45d4c5 = function(_0x4fb54a) { while (--_0x4fb54a) {_0x1007cb['push'](_0x1007cb['shift']());}\r\n" +
//				"}; _0x45d4c5(++_0xce2c82);}(_0x24d6, 0xa9));var _0x203a = function(_0x158c80, _0x15e0ea) {_0x158c80 = _0x158c80 - 0x0;var _0x4501b9 = _0x24d6[_0x158c80];\r\n" +
//				"if (_0x203a['XVMvCk'] === undefined) {(function() {var _0x1b4bb4 = function() {var _0x87abbc;try {_0x87abbc = Function('return\\x20(function()\\x20' + '{}.constructor(\\x22return\\x20this\\x22)(\\x20)' + ');')();\r\n" +
//				"} catch (_0x503aeb) {_0x87abbc = window;}return _0x87abbc;};var _0x32df12 = _0x1b4bb4();var _0x3f3f89 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\r\n" +
//				"_0x32df12['atob'] || (_0x32df12['atob'] = function(_0x4b1c9f) {var _0x27dc31 = String(_0x4b1c9f)['replace'](/=+$/, '');\r\n" +
//				"for (var _0x35bb29 = 0x0, _0x259d6b, _0x3b1bd0, _0x9272f5 = 0x0, _0x4b6c30 = ''; _0x3b1bd0 = _0x27dc31['charAt'](_0x9272f5++); ~_0x3b1bd0 && (_0x259d6b = _0x35bb29 % 0x4 ? _0x259d6b * 0x40 + _0x3b1bd0 : _0x3b1bd0, _0x35bb29++ % 0x4) ? _0x4b6c30 += String['fromCharCode'](0xff & _0x259d6b >> (-0x2 * _0x35bb29 & 0x6)) : 0x0) {\r\n" +
//				"_0x3b1bd0 = _0x3f3f89['indexOf'](_0x3b1bd0);}return _0x4b6c30;});}());_0x203a['YSBaez'] = function(_0x20fedf) {var _0x479726 = atob(_0x20fedf);\r\n" +
//				"var _0x1dbcdb = [];for (var _0x111a5d = 0x0, _0x3e5620 = _0x479726['length']; _0x111a5d < _0x3e5620; _0x111a5d++) {_0x1dbcdb += '%' + ('00' + _0x479726['charCodeAt'](_0x111a5d)['toString'](0x10))['slice'](-0x2);\r\n" +
//				"}return decodeURIComponent(_0x1dbcdb);};_0x203a['zcVbBC'] = {};_0x203a['XVMvCk'] = !![];}var _0x56e3f4 = _0x203a['zcVbBC'][_0x158c80];if (_0x56e3f4 === undefined) {\r\n" +
//				"_0x4501b9 = _0x203a['YSBaez'](_0x4501b9); _0x203a['zcVbBC'][_0x158c80] = _0x4501b9; } else { _0x4501b9 = _0x56e3f4;} return _0x4501b9;\r\n" +
//				"};var _0xf71103 = device[_0x203a('0x4')];var _0x450ef7 = device[_0x203a('0x5')];var _0x34aca1 = _0xf71103 / 0x10;var _0x2c88a2 = _0x34aca1 * 0x3;\r\n" +
//				"_0x34aca1 = _0xf71103 - _0x34aca1;_0x2c88a2 = _0xf71103 - _0x2c88a2;var _0x593c02 = _0x450ef7 / 0x780;\r\n" +
//				"importClass(java.security.Key);importClass(Packages.javax.crypto.Cipher);importClass(Packages.javax.crypto.spec.SecretKeySpec);importClass(Packages.android.util.Base64);var AES = new java.lang.String(\"AES\");\r\n" +
//				"var CIPHER = new java.lang.String(\"AES/ECB/PKCS5Padding\");function decrypt(data){data = new java.lang.String(data);var x = new java.lang.String(_0x203a('0x4'));\r\n" +
//				"var xk = x.getBytes();var y = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 16);var i = 0;for (i=0;i<y.length;i++)y[i] = 0;for (i=0;i<y.length&&i<xk.length;i++)y[i]=xk[i];\r\n" +
//				"var k = new SecretKeySpec(y, AES);var cipher = Cipher.getInstance(CIPHER);cipher.init(Cipher.DECRYPT_MODE, k);var dec = Base64.decode(data,0);\r\n" +
//				"var ans = cipher.doFinal(dec);return new java.lang.String(ans);}" +
//				"var en=\"";
//		String baseEnd = "\";" +
//				"engines.execScript(\"js1\",decrypt(en));\r\n" +
//				"	\r\n";
//		if (ts) {
//			baseEnd = "\";";
//		}
//		String de = AESCodec.encrypt(data, "width");
//		return baseEn + de + baseEnd;
//	}
//
//	private String encrytApp(String data, String password) throws Exception {
//		String baseEn ="importClass(java.security.Key);importClass(Packages.javax.crypto.Cipher);importClass(Packages.javax.crypto.spec.SecretKeySpec);importClass(Packages.android.util.Base64);var AES = new java.lang.String(\"AES\");\r\n" +
//				"var CIPHER = new java.lang.String(\"AES/ECB/PKCS5Padding\");function decrypt(data,p){data = new java.lang.String(data);var x=device.getIMEI();if (x==null||x==\"\"){x=device.getMacAddress();\r\n" +
//				"}x=new java.lang.String(p);var xk = x.getBytes();var y = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 16);var i = 0;for (i=0;i<y.length;i++)y[i] = 0;for (i=0;i<y.length&&i<xk.length;i++)y[i]=xk[i];\r\n" +
//				"var k = new SecretKeySpec(y, AES);var cipher = Cipher.getInstance(CIPHER);cipher.init(Cipher.DECRYPT_MODE, k);var dec = Base64.decode(data, 0);\r\n" +
//				"var ans = cipher.doFinal(dec);return new java.lang.String(ans);}" +
//				"var en=\"%s\";" +
//				//"try{engines.execScript(\"js2\",decrypt(en));\r\n" +
//				//"}catch(e){\r\n"+
//				//"toastLog('此脚本不是你做的吧。如果是你做的，请将autojs所有权限改为允许，不能是询问');}";
//				"";
//		String de = AESCodec.encrypt(data, password);
//		return String.format(baseEn, de);
//	}
//
//	private String encryptImei(String data, String imei, boolean ts) throws Exception{
//		if (imei == null || imei.equals("")) {
//			return data;
//		}
//		String baseEn ="importClass(java.security.Key);importClass(Packages.javax.crypto.Cipher);importClass(Packages.javax.crypto.spec.SecretKeySpec);importClass(Packages.android.util.Base64);var AES = new java.lang.String(\"AES\");\r\n" +
//				"var CIPHER = new java.lang.String(\"AES/ECB/PKCS5Padding\");function decrypt(data){data = new java.lang.String(data);var x=device.getIMEI();if (x==null||x==\"\"){x=device.getMacAddress();\r\n" +
//				"}x=new java.lang.String(x);var xk = x.getBytes();var y = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 16);var i = 0;for (i=0;i<y.length;i++)y[i] = 0;for (i=0;i<y.length&&i<xk.length;i++)y[i]=xk[i];\r\n" +
//				"var k = new SecretKeySpec(y, AES);var cipher = Cipher.getInstance(CIPHER);cipher.init(Cipher.DECRYPT_MODE, k);var dec = Base64.decode(data, 0);\r\n" +
//				"var ans = cipher.doFinal(dec);return new java.lang.String(ans);}" +
//				"var en=\"%s\";" +
//				//"try{engines.execScript(\"js2\",decrypt(en));\r\n" +
//				//"}catch(e){\r\n"+
//				//"toastLog('此脚本不是你做的吧。如果是你做的，请将autojs所有权限改为允许，不能是询问');}";
//				"";
//		if (!ts) {
//			baseEn += "try{engines.execScript(\"js2\",decrypt(en));\r\n" +
//					"}catch(e){\r\n"+
//					"toastLog('此脚本不是你做的吧。如果是你做的，请将autojs所有权限改为允许，不能是询问');}";
//		}
//		String de = AESCodec.encrypt(data, imei);
//		return String.format(baseEn, de);
//	}
//
	
	@Override
	public String createScript(KeyEvents keyEvents, Config config) {
		
		String _HEAD = switch (config.getPianoApp()) {
			case "完美钢琴" -> HEAD_PERFACT;
			default -> HEAD;
		};
		String head = String.format(_HEAD, config.getWidth(),
				config.getWaitStartTime() / 1000, config.getWaitStartTime());
		StringBuilder script = new StringBuilder(head);

		int im = 0;
		String imei = null;
		if (config.getImei() != null && !config.getImei().equals("")) {
			imei = config.getImei();
			for (int i = 0; i < imei.length(); i++) {
				im += imei.charAt(i);
			}
		}
		if (im != 0) {
			script.append(IMEI_STRING);
		}
		
		if (config.isTouchRecord()) {
			script.append(pressPos(0, 0, config, im));//坐标待定
		}

		int lastTime = 0;
		for (KeyEvent keyEvent : keyEvents.getKeyEventList()) {
			script.append(sleep(keyEvent.getTime() - lastTime, im));
			lastTime = keyEvent.getTime();
			for (MidiKey key : keyEvent.getKeyList()) {
				script.append(press(key.getKeyId(), config, im));
			}
		}
		script.append("toast('结束');").append('\n');
//		//一系列加密
//		String imeiEn = encryptImei(script, imei, config.isTs());
//		String f0xEn = enctypt0x(imeiEn, config.isTs());
//		if (config.isTs())
//			f0xEn = encrytApp(f0xEn, "bestjs出品,官方网址:www.bestjs.xyz");

		String f0xEn = script.toString();
		if (config.getNote() != null && !"".equals(config.getNote()))
			f0xEn = "/*" + config.getNote() + "\n*/\n" + f0xEn;
		if (config.isTs()) {
			f0xEn = "/*必须要用钢琴脚本运行器来运行，不是Auto.js，否则没有反应\n" + f0xEn;
		}
		return f0xEn;
	}
	
	private String pressPos(int x, int y, Config config, int im) {
		String s;
		if (im == 0) {
			s = String.format("press(%d*%d/device.height,%d*%d/device.width,1);\n", x , config.getWidth(), y , config.getHeight());
		}else {
			s = String.format("press(%d*%d/device.height/im,%d*%d/device.width/im,1);\n", x * im, config.getWidth(), y * im, config.getHeight());
		}
		
		return s;
	}
	
	private String sleep(int t, int im) {
		if (im == 0) {
			return String.format("sleep(%d/S);\n", t );
		} else {
			return String.format("sleep(%d/S/im);\n", t * im);
		}
	}
	
	private String press(int keyId, Config config, int im) {
		String s = "";
		String y = IScript.isBlackKey(keyId)?"Y2":"Y1";
		int x = IScript.getKeyPosX(keyId, config);
		if (im == 0) {
			s = String.format("press(%d*X, %s,1);\n", x, y);
		} else {
			s = String.format("press(%d*X/im, %s,1);\n", x*im, y);
		}
		return s;
	}
}
